package HLA2.federate;

/*
 *   Copyright 2007 The Portico Project
 *
 *   This file is part of portico.
 *
 *   portico is free software; you can redistribute it and/or modify
 *   it under the terms of the Common Developer and Distribution License (CDDL) 
 *   as published by Sun Microsystems. For more information see the LICENSE file.
 *   
 *   Use of this software is strictly AT YOUR OWN RISK!!!
 *   If something bad happens you do not have permission to come crying to me.
 *   (that goes for your lawyer as well)
 *
 */



import hla.rti.ArrayIndexOutOfBounds;
import hla.rti.EventRetractionHandle;
import hla.rti.LogicalTime;
import hla.rti.RTIexception;
import hla.rti.ReceivedInteraction;
import hla.rti.ReflectedAttributes;
import hla.rti.jlc.EncodingHelpers;
import hla.rti.jlc.NullFederateAmbassador;

import java.util.logging.Level;
import java.util.logging.Logger;
import org.portico.impl.hla13.types.DoubleTime;

/**
 * This class handles all incoming callbacks from the RTI regarding a particular
 * {@link Example13Federate}. It will log information about any callbacks it
 * receives, thus demonstrating how to deal with the provided callback information.
 */
public class Federate2Ambassador extends NullFederateAmbassador
{
	static Federate2 fed2 = new Federate2();
	public boolean fine = false;
	public boolean disk1 = false;
	public boolean disk2 = false;
	public boolean oss = false;
	public double random;
	public int job;
	public boolean gestisciD1 = false;
	public boolean gestisciD2 = false;
	
	// these variables are accessible in the package
	public double federateTime        = 0.0;
	protected double federateLookahead   = 1.0;

	protected boolean isRegulating       = false;
	protected boolean isConstrained      = false;
	protected boolean isAdvancing        = false;

	protected boolean isAnnounced        = false;
	protected boolean isReadyToRun       = false;

	
	private double convertTime( LogicalTime logicalTime )
	{
		// PORTICO SPECIFIC!!
		return ((DoubleTime)logicalTime).getTime();
	}

	private void log( String message )
	{
		System.out.println( "FederateAmbassador2: " + message );
	}

	//////////////////////////////////////////////////////////////////////////
	////////////////////////// RTI Callback Methods //////////////////////////
	//////////////////////////////////////////////////////////////////////////
	public void synchronizationPointRegistrationFailed( String label )
	{
		log( "Failed to register sync point: " + label );
	}

	public void synchronizationPointRegistrationSucceeded( String label )
	{
		log( "Successfully registered sync point: " + label );
	}

	public void announceSynchronizationPoint( String label, byte[] tag )
	{
		log( "Synchronization point announced: " + label );
		if( label.equals(Federate2.READY_TO_RUN) )
			this.isAnnounced = true;
	}

	public void federationSynchronized( String label )
	{
		log( "Federation Synchronized: " + label );
		if( label.equals(Federate2.READY_TO_RUN) )
			this.isReadyToRun = true;
	}

	/**
	 * The RTI has informed us that time regulation is now enabled.
	 */
	public void timeRegulationEnabled( LogicalTime theFederateTime )
	{
		this.federateTime = convertTime( theFederateTime );
		this.isRegulating = true;
	}

	public void timeConstrainedEnabled( LogicalTime theFederateTime )
	{
		this.federateTime = convertTime( theFederateTime );
		this.isConstrained = true;
	}

	public void timeAdvanceGrant( LogicalTime theTime )
	{
		this.federateTime = convertTime( theTime );
		this.isAdvancing = false;
	}

	public void discoverObjectInstance( int theObject,
			int theObjectClass,
			String objectName )
	{
		log( "Discoverd Object: handle=" + theObject + ", classHandle=" +
				theObjectClass + ", name=" + objectName );
	}

//	public void reflectAttributeValues( int theObject,
//			ReflectedAttributes theAttributes,
//			byte[] tag )
//	{
//		reflectAttributeValues( theObject, theAttributes, tag, null, null );
//	}

	public void reflectAttributeValues( int theObject,
			ReflectedAttributes theAttributes,
			byte[] tag,
			LogicalTime theTime,
			EventRetractionHandle retractionHandle )
	{	
		
		String s = EncodingHelpers.decodeString(tag);
		if (s.equalsIgnoreCase("semeD1"))
		{
			try {
				random = EncodingHelpers.decodeDouble(theAttributes.getValue(0));
//				*********************************************************************
//				System.out.println("Ricevuto attributo seme1: " + random);
//				*********************************************************************
			} catch (ArrayIndexOutOfBounds ex) {
				Logger.getLogger(Federate2Ambassador.class.getName()).log(Level.SEVERE, null, ex);
			}
		}
		if (s.equalsIgnoreCase("semeD2"))
		{
			try {
				random = EncodingHelpers.decodeDouble(theAttributes.getValue(0));
//				*********************************************************************
//				System.out.println("Ricevuto attributo semeD2: " + random);
//				*********************************************************************
			} catch (ArrayIndexOutOfBounds ex) {
				Logger.getLogger(Federate2Ambassador.class.getName()).log(Level.SEVERE, null, ex);
			}
		}

		if (s.equalsIgnoreCase("d1"))
		{
			disk1=true;
			try {
				job = EncodingHelpers.decodeInt(theAttributes.getValue(0));
//				*********************************************************************
//				System.out.println("Ricevuto attributo d1: job = " +job+" disk1 = " + disk1);
//				*********************************************************************
			} catch (ArrayIndexOutOfBounds e) {
				e.printStackTrace();
			}
		}
		if (s.equalsIgnoreCase("d2"))
		{
			disk2=true;
			try {
				job = EncodingHelpers.decodeInt(theAttributes.getValue(0));
//				*********************************************************************
//				System.out.println("Ricevuto attributo d2: job = " +job+" disk2 = " + disk2);
//				*********************************************************************
			} catch (ArrayIndexOutOfBounds e) {
				e.printStackTrace();
			}
		}
		if (s.equalsIgnoreCase("gestisciD1"))
		{
			try {
				job = EncodingHelpers.decodeInt(theAttributes.getValue(0));
				gestisciD1=true;
//				*********************************************************************
//				System.out.println("Ricevuto attributo gestisciD1: job = " +job  + " gestisciD1 "+gestisciD1);
//				*********************************************************************
			} catch (ArrayIndexOutOfBounds e) {
				e.printStackTrace();
			}
			
		}
		if (s.equalsIgnoreCase("gestisciD2"))
		{
			try {
				job = EncodingHelpers.decodeInt(theAttributes.getValue(0));
				gestisciD2 = true;
//				*********************************************************************
//				System.out.println("Ricevuto attributo gestisciD2: job = " +job  + " gestisciD2 "+gestisciD2);
//				*********************************************************************
			} catch (ArrayIndexOutOfBounds e) {
				e.printStackTrace();
			}
		}
		

	}

	public void receiveInteraction( int interactionClass,
			ReceivedInteraction theInteraction,
			byte[] tag )
	{
		// just pass it on to the other method for printing purposes
		// passing null as the time will let the other method know it
		// it from us, not from the RTI
		receiveInteraction( interactionClass, theInteraction, tag, null, null );
	}

	public void receiveInteraction( int interactionClass,
			ReceivedInteraction theInteraction,
			byte[] tag,
			LogicalTime theTime,
			EventRetractionHandle eventRetractionHandle )
	{
		String s = EncodingHelpers.decodeString(tag);
		//analisi dei vari tag che arrivano

		if(s.equalsIgnoreCase("fine"))          //ricevo fineSimulazione e interrompo "main"
			fine = true;
		if(s.equalsIgnoreCase("oss"))             //restituisci stato disk2
			oss = true;

	}

	public void removeObjectInstance( int theObject, byte[] userSuppliedTag )
	{
		log( "Object Removed: handle=" + theObject );
	}

	public void removeObjectInstance( int theObject,
			byte[] userSuppliedTag,
			LogicalTime theTime,
			EventRetractionHandle retractionHandle )
	{
		log( "Object Removed: handle=" + theObject );
	}
}
